#include<iostream>
#include<map>
#include<string>
using namespace std;

class Viewer;
class Model;
class IControler
{
public:
	virtual void Register( Model *pModel, Viewer* pViewer) = 0;
	virtual void UnRegister( Model *pModel, Viewer* pViewer) = 0;
	virtual	void Notify(Model *pModel) = 0;
};

class Model
{
public:
	Model(string state)
	{
		m_sState = state;
	}
	string GetState()
	{
		return m_sState;
	}
	void Register(Viewer *pViewer)
	{
		m_pControler->Register(this, pViewer);
	}
	void UnRegister(Viewer *pViewer)
	{
		m_pControler->UnRegister(this, pViewer);
	}
	void Notify()
	{
		m_pControler->Notify(this);
	}
	void SetIControler(IControler *pControler)
	{
		m_pControler = pControler;
	}
private:
	string m_sState;
	IControler * m_pControler;
};

class Viewer 
{
public:
	Viewer(string name)
	{
		m_sName = name;
	}
	void Update(Model *pModel)
	{
		cout<<m_sName<<"  "<<pModel->GetState()<<endl;
	}
private:
	string m_sName;
};

class Controler: public IControler
{
public:
	Controler()
	{

	}
	virtual ~Controler(){}
	virtual void Register( Model *pModel, Viewer* pViewer)
	{
		m_VMMap.insert(make_pair( pModel, pViewer));
	}
	virtual void UnRegister( Model *pModel, Viewer *pViewer)
	{
		multimap< Model*, Viewer*>::iterator ite =m_VMMap.begin() ;
		while (ite != m_VMMap.end())
		{
			if (ite->first==pModel && ite->second == pViewer)
			{
				m_VMMap.erase(ite++);
			}
			else
			{
				ite++;
			}
		}
	}
	virtual void Notify(Model *pModel)
	{
		multimap< Model*, Viewer*>::iterator ite ;
		ite = m_VMMap.lower_bound(pModel);
		while (ite != m_VMMap.upper_bound(pModel))
		{
				ite->second->Update(ite->first);
				ite++;
		}
	}
private:
	multimap< Model*, Viewer*> m_VMMap;
};
int main8()
{
	IControler *pControler = new Controler();

	Viewer *pViewer1 = new Viewer("John");
	Viewer *pViewer2 = new Viewer("Tom");

	Model *pModel1 = new Model("There is a new white house");
	pModel1->SetIControler(pControler);
	pModel1->Register(pViewer1);
	pModel1->Register(pViewer2);
	pModel1->Notify();
	pModel1->UnRegister(pViewer1);
	pModel1->Notify();
	cout<<"**********************************"<<endl;

	Model *pModel2 = new Model("There is a new blue house");
	pModel2->SetIControler(pControler);
	pModel2->Register(pViewer1);
	pModel2->Register(pViewer2);
	pModel2->Notify();

	delete pModel2;
	delete pModel1;
	delete pViewer2;
	delete pViewer1;
	delete pControler;

	cin.get();
	return 0;
}